package com.service.business.pay.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.beust.jcommander.internal.Lists;
import com.service.business.base.dto.LoginUserSession;
import com.service.business.base.service.CoinsPriceService;
import com.service.business.member.dto.MemberStoreChange;
import com.service.business.member.service.*;
import com.service.business.order.service.OrderProductHrComboDetailsService;
import com.service.business.order.service.OrderProductHrComboService;
import com.service.business.order.service.OrderProductLockComboService;
import com.service.business.order.service.OrderProductOtherService;
import com.service.business.pay.controller.rep.PayRecord;
import com.service.business.pay.controller.rep.PayTypeRep;
import com.service.business.pay.controller.req.PayOrderReq;
import com.service.business.pay.dto.PayOrder;
import com.service.business.pay.service.PayService;
import com.service.business.product.service.ProductHrComboService;
import com.service.business.product.service.ProductPayTypeService;
import com.service.business.support.*;
import com.service.business.utils.DateUtil;
import com.service.business.utils.I18nUtil;
import com.service.core.exception.CommonException;
import com.service.dao.constants.ConfigConstants;
import com.service.dao.enums.*;
import com.service.dao.mapper.MemberGradeConfigMapper;
import com.service.dao.mapper.SysConfigMapper;
import com.service.dao.model.*;
import com.service.dao.po.MemberCache;
import com.service.utility.common.MathUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.redisson.RedissonRedLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * <dl>
 * <dt>back-end</dt>
 * <dd>Description:</dd>
 * <dd>Copyright: Copyright (C) 2015</dd>
 * <dd>Company: </dd>
 * <dd>CreateDate: 2019年11月15日</dd>
 * </dl>
 *
 * @author
 */
@Service
@Slf4j
@SuppressWarnings("all")
public class PayServiceImpl implements PayService {
	@Autowired
	private MemberStoreLockUtils memberStoreLockUtils;
	@Autowired
	private MemberCacheUtils memberCacheUtils;
	@Autowired
	private SessionUtil sessionUtil;
	@Autowired
	private MemberService memberService;
	@Autowired
	private MemberJAService memberJAService;
	@Autowired
	private CoinsPriceService coinsPriceService;
	@Autowired
	private MemberStoreService memberStoreService;
	@Autowired
	private SysConfigMapper sysConfigMapper;
	@Autowired
	private ProductPayTypeService productPayTypeService;
	@Autowired
	private ProductHrComboService productHrComboService;
	@Autowired
	private OrderProductOtherService orderProductOtherService;
	@Autowired
	private OrderProductHrComboService orderProductHrComboService;
	@Autowired
	private OrderProductLockComboService orderProductLockComboService;
	@Autowired
	private OrderProductHrComboDetailsService orderProductHrComboDetailsService;
	@Autowired
	private MemberGradeConfigService gradeConfigService;
	@Autowired
	private MemberCacheService memberCacheService;
	@Autowired
	private OrderLockUtils orderLockUtils;

	private final static BigDecimal ONE_HUNDRED = BigDecimal.valueOf(100);

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void payProductOtherOrder(String orderNo, OrderProductOther orderProductOther, Map<String, BigDecimal> totalMap, List<OrderProductOtherTotal> totalList, Map<String, SysConfig> configMap) {
		LoginUserSession session = sessionUtil.getUser();

		Map<String, BigDecimal> payMoney = totalMap.entrySet().stream()
				.filter(item -> !(checkGiftCoin(item.getKey(), configMap)))
				.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

		Map<String, BigDecimal> giftNumMap = totalMap.entrySet().stream()
				.filter(item -> checkGiftCoin(item.getKey(), configMap))
				.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

		payByMemberStore(session.getUserId(), payMoney, MemberJAType.PAY_OTHER, orderProductOther.getId());

		if (!ObjectUtils.isEmpty(giftNumMap)) {
			for (String coin : giftNumMap.keySet()) {
				//赠送积分
				memberStoreService.getPointsByPayOrder(orderProductOther.getMemberId(), giftNumMap.get(coin), coin, orderProductOther.getId());
			}
		}
		List<OrderProductOtherTotal> giftOrderTotalList = totalList.stream().filter(item -> ObjectUtils.nullSafeEquals(item.getProductType(), OrderTypeEnum.OTHER_GIFT.getCode())).collect(Collectors.toList());

		OrderProductOther updateOrder = new OrderProductOther();
		updateOrder.setId(orderProductOther.getId());
		updateOrder.setPayMoney(orderProductOther.getOrderMoney());
		updateOrder.setPayTime(new Date());
		updateOrder.setReleaseAward(ObjectUtils.isEmpty(giftOrderTotalList) ? OrderReleaseAwardEnum.RELEASE.getCode() : OrderReleaseAwardEnum.NOT_RELEASE.getCode());
		updateOrder.setOrderStatus(OrderProductOtherStatus.PAYED.getCode());
		orderProductOtherService.updateById(updateOrder);

		if (!ObjectUtils.isEmpty(giftOrderTotalList)) {
			AtomicReference<BigDecimal> totalPayMoney = new AtomicReference<>(BigDecimal.ZERO);
			giftOrderTotalList.forEach(item -> {
				totalPayMoney.accumulateAndGet(item.getTotalPrice(), BigDecimal::add);
				if (StringUtils.equals(item.getTotalPriceCoin(), item.getTotalFreightCoin())) {
					totalPayMoney.accumulateAndGet(item.getTotalFreight(), BigDecimal::add);
				}
			});
			updateOrder.setPayMoney(totalPayMoney.get());
//            giftOrderSendHandler.sendPayGiftOrderMsg(buildPayOrderMsg(session.getUserId(), updateOrder));
		}

	}

	private boolean checkGiftCoin(String key, Map<String, SysConfig> configMap) {
		return StringUtils.equals(key, configMap.get(ConfigConstants.GIFT_ORDER_GIFT_COINS).getConfOptions())
				|| StringUtils.equals(key, configMap.get(ConfigConstants.POINTS_ORDER_GIFT_COINS).getConfOptions());
	}

	private PayOrder buildPayOrderMsg(Integer memberId, OrderProductOther orderProductOther) {
		return PayOrder.builder()
				.orderId(orderProductOther.getId())
				.memberId(memberId)
				.payMoney(orderProductOther.getPayMoney())
				.build();
	}

	private void payByMemberStore(Integer memberId, Map<String, BigDecimal> totalMap, MemberJAType payType, Integer orderId) {
		for (String item : totalMap.keySet()) {
			if (!memberStoreService.enoughOfBalance(memberId, item, totalMap.get(item))) {
				String msg = I18nUtil.getMessage("store_balance_exception_not_enough", Language.LANG.get(), CoinsEnum.EXDF.getName());
				throw new CommonException(msg);
			}
			memberStoreService.payByMemberStore(memberId, item, payType, totalMap.get(item), orderId);
		}
	}

	private void payByMemberStore(Integer memberId, List<PayTypeRep> payTypeRepList, MemberJAType payType, BigDecimal payMoney, Integer orderId) {
		if (!isEnoughPayOrder(payMoney, memberId, payTypeRepList)) {
			throw new CommonException("支付失败，会员余额不足", "order_pay_info_exception_store_enough");
		}
		for (PayTypeRep payTypeRep : payTypeRepList) {
			memberStoreService.payByMemberStore(memberId, payTypeRep.getCoinsName(), payType, payTypeRep.getPayMoney(), orderId);
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void payProductHrComboOrder(String orderNo, OrderProductHrCombo orderProductHrCombo, List<PayTypeRep> payTypeRepList, PayOrderReq payOrderReq) {
		LoginUserSession session = sessionUtil.getUser();
		memberService.validSafetyPwd(session.getUserId(), payOrderReq.getSafetyPwd());
		//获取算力订单详情
		OrderProductHrComboDetails orderProductHrComboDetails = orderProductHrComboDetailsService.getOne(new QueryWrapper<OrderProductHrComboDetails>().lambda()
			.eq(OrderProductHrComboDetails::getHrOrderId,orderProductHrCombo.getId())
		);
		payByMemberStore(session.getUserId(), payTypeRepList, MemberJAType.PAY_HR_COMBO, orderProductHrCombo.getOrderMoney(), orderProductHrCombo.getId());

		OrderProductHrComboDetails comboDetails = orderProductHrComboDetailsService.updateHrComboInterval(orderProductHrCombo.getId());
		log.info("商品编号<{}>", comboDetails.getComboId());
		ProductHrCombo combo = productHrComboService.getById(comboDetails.getComboId());

		if (!ObjectUtils.isEmpty(combo) && combo.getLimitBuyNum() > 0) {
			Integer memberId = sessionUtil.getUser().getUserId();
			Integer totalOrderCount = orderProductHrComboService.totalEffectiveOrderByMemberIdAndComboId(memberId, combo.getId());
			if (totalOrderCount >= combo.getLimitBuyNum()) {
				throw new CommonException("已达到该产品限购数量", "hash_rate_combo_limit_num");
			}
		}
		OrderProductHrCombo updateOrder = new OrderProductHrCombo();
		updateOrder.setId(orderProductHrCombo.getId());
		updateOrder.setPayMoney(orderProductHrCombo.getOrderMoney());
		updateOrder.setPayTypeGroup(payOrderReq.getPayGroup());
		updateOrder.setPayTime(new Date());
		updateOrder.setOrderStatus(OrderProductOtherStatus.PAYED.getCode());
		boolean saveFlag = orderProductHrComboService.updateById(updateOrder);
		if(saveFlag){
			//直推奖励发放
			payOrderShareDirect2TopU(orderProductHrCombo,orderProductHrComboDetails);
			//业绩奖励发放
			sendTeamPerformanceReward(orderProductHrCombo,orderProductHrComboDetails);
		}
		//缓存用户消费累计信息
//		MemberCache memberCache = memberCacheUtils.getMemberCache(orderProductHrCombo.getMemberId());
//		if(!ObjectUtils.isEmpty(memberCache)){
//			memberCache.setValidMember(true);
//			memberCache.setTotalConsumption(memberCache.getTotalConsumption().add(orderProductHrCombo.getTotalHashRate()));
//			memberCacheUtils.setMemberCache(memberCache);
//		}
//		//更新等级
//		memberService.checkAndUpdateMemberGrade(session.getUserId());
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void pay(PayOrderReq payOrderReq, LoginUserSession session, String orderNo) {
		memberService.validSafetyPwd(session.getUserId(), payOrderReq.getSafetyPwd());

		OrderProductHrCombo orderProductHrCombo = orderProductHrComboService.getOrderDetailByOrderNo4Pay(orderNo);
		OrderProductHrComboDetails orderProductHrComboDetails = orderProductHrComboDetailsService.getOne(new QueryWrapper<OrderProductHrComboDetails>().lambda()
				.eq(OrderProductHrComboDetails::getHrOrderId, orderProductHrCombo.getId())
		);
		//判断产品购买是否需要质押对应购买币种
		if(orderProductHrComboDetails.getNeedPledge() == CommonStatusEnums.ACTIVE.getCode()){
			MemberStore memberFILStore = memberStoreService.getMemberStore(session.getUserId(), orderProductHrComboDetails.getFromCoinsName());
			BigDecimal needPledgeNum = orderProductHrComboDetails.getPledgeNum().multiply(new BigDecimal(orderProductHrComboDetails.getOrderNum()));
			boolean isLockFIL = memberStoreLockUtils.lock(session.getUserId(), orderProductHrComboDetails.getFromCoinsId());
			if (!isLockFIL) {
				log.info("账户{}已被锁定", session.getUserId());
			}
			if (memberFILStore.getNum().compareTo(needPledgeNum) < 0) {
				throw new CommonException("会员余额不足", "store_balance_not_enough");
			}
			if (memberFILStore.getNum().compareTo(needPledgeNum) < 0) {
				throw new CommonException("会员余额不足", "store_balance_not_enough");
			}
			memberStoreService.changeMemberStore(
					MemberStoreChange.builder()
							.memberId(session.getUserId())
							.coinsId(orderProductHrComboDetails.getFromCoinsId())
							.coinsName(orderProductHrComboDetails.getFromCoinsName())
							.jaType(MemberJAType.RENEW_FIL_PLEDGE)
							.orderId(orderProductHrCombo.getId())
							.custodyFee(BigDecimal.ZERO)
							.orderDetailId(orderProductHrComboDetails.getId())
							.changeNum(needPledgeNum)
							.remark(orderProductHrCombo.getMemberId() + MemberJAType.RENEW_FIL_PLEDGE.getMsg().toString())
							.build());
			memberStoreLockUtils.unlock(session.getUserId(), orderProductHrComboDetails.getFromCoinsId());
		}
		//判断产品购买是否需要对应购买币种作为gas
		if(orderProductHrComboDetails.getNeedGas() == CommonStatusEnums.ACTIVE.getCode()){
			BigDecimal needGasNum = orderProductHrComboDetails.getGasNum().multiply(new BigDecimal(orderProductHrComboDetails.getOrderNum()));
			MemberStore memberFILGasStore = memberStoreService.getMemberStore(session.getUserId(), orderProductHrComboDetails.getFromCoinsName());
			boolean isLockFILGas = memberStoreLockUtils.lock(session.getUserId(), orderProductHrComboDetails.getFromCoinsId());
			if (!isLockFILGas) {
				log.info("账户{}已被锁定", session.getUserId());
			}
			if (memberFILGasStore.getNum().compareTo(needGasNum) < 0) {
				throw new CommonException("GAS不足", "store_balance_not_enough");
			}
			memberStoreService.changeMemberStore(
					MemberStoreChange.builder()
							.memberId(session.getUserId())
							.coinsId(orderProductHrComboDetails.getFromCoinsId())
							.coinsName(orderProductHrComboDetails.getFromCoinsName())
							.jaType(MemberJAType.RENEW_FIL_GAS)
							.orderId(orderProductHrCombo.getId())
							.custodyFee(BigDecimal.ZERO)
							.orderDetailId(orderProductHrComboDetails.getId())
							.changeNum(needGasNum)
							.remark(orderProductHrCombo.getMemberId() + MemberJAType.RENEW_FIL_GAS.getMsg().toString())
							.build());
			memberStoreLockUtils.unlock(session.getUserId(), orderProductHrComboDetails.getFromCoinsId());
		}

		List<String> lockKey = Lists.newArrayList(orderLockUtils.buildHrOrderLockKey(orderNo));
		List<PayTypeRep> payTypeRepList = buildMemberStoreKeyAndPayTypeList(orderProductHrCombo.getOrderType(), payOrderReq.getPayGroup(), session, lockKey);
		RedissonRedLock redLock = orderLockUtils.getRedLock(lockKey);
		if (orderLockUtils.redLockTryLock(redLock)) {
			try {
				payProductHrComboOrder(orderNo, orderProductHrCombo, payTypeRepList, payOrderReq);
			} finally {
				redLock.unlock();
			}
		}
	}

	private List<PayTypeRep> buildMemberStoreKeyAndPayTypeList(Integer orderType, Integer payGroup, LoginUserSession session, List<String> lockKey) {
		List<PayTypeRep> payTypeRepList = productPayTypeService.listByOrderTypeAndPayGroup(orderType, payGroup);
		for (PayTypeRep payTypeRep : payTypeRepList) {
			MemberStore memberStore = memberStoreService.getMemberStore(session.getUserId(), payTypeRep.getCoinsName());
			lockKey.add(MemberStoreLockUtils.buildStoreKey(memberStore.getMemberId(), memberStore.getId()));
		}
		return payTypeRepList;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void payProductLockComboOrder(String lockNo, OrderProductLockCombo orderProductLockCombo, List<PayTypeRep> payTypeRepList, PayOrderReq payOrderReq) {
		LoginUserSession session = sessionUtil.getUser();
		memberService.validSafetyPwd(session.getUserId(), payOrderReq.getSafetyPwd());

		payByMemberStore(session.getUserId(), payTypeRepList, MemberJAType.PAY_LOCK_MINING, orderProductLockCombo.getLockNum(), orderProductLockCombo.getId());

		orderProductLockCombo.setPayTypeGroup(payOrderReq.getPayGroup());
		orderProductLockCombo.setOrderStatus(HashRateOrderEnums.Status.payed_effective.getCode());
		Date current = new Date();
		Date startTime = DateUtil.getDayOfStart(DateUtil.addDay(current, 1));
		Date endTime = DateUtil.addDay(startTime, orderProductLockCombo.getLockDay());
		orderProductLockCombo.setPayTime(current);
		orderProductLockCombo.setStartTime(startTime);
		orderProductLockCombo.setEndTime(endTime);
		boolean saveFlag = orderProductLockComboService.updateById(orderProductLockCombo);
	}


	/**
	 * 支付成功后续处理直推返U操作
	 *
	 * @param orderProductHrCombo
	 * @param comboDetails
	 */
	public void payOrderShareDirect2TopU(OrderProductHrCombo orderProductHrCombo, OrderProductHrComboDetails comboDetails) {
		//查询当前用户的上一级直推用户
		Member top1Member = memberService.getMemberTop1(orderProductHrCombo.getMemberId());
		if (ObjectUtils.isEmpty(top1Member)) {
			return;
		}
		BigDecimal topEffect = orderProductHrComboService.totalEffectiveOrderAndStatusByMemberId(top1Member.getId());
		if(topEffect.compareTo(new BigDecimal(0)) <= 0){
			return;
		}
		Member me = memberService.getMemberById(orderProductHrCombo.getMemberId());
		if (ObjectUtils.isEmpty(me)) {
			return;
		}
		MemberGradeConfig meGradeConfig = gradeConfigService.getById(me.getVipGrade());
		//获取父级用户的等级配置
		MemberGradeConfig topGradeConfig = gradeConfigService.getById(top1Member.getVipGrade());
//
//		//计算等级差
//		if(meGradeConfig.getId() >= topGradeConfig.getId()){
//			log.info("用户{}与上级推荐用户{}存在极差，不满足发放直推奖条件，退出当前直推奖流程...",me.getUserAccount() ,top1Member.getUserAccount());
//			return;
//		}
//		BigDecimal rewardRateDivValue = MathUtil.div(topGradeConfig.getDirectRewardRate(),meGradeConfig.getDirectRewardRate());
		BigDecimal rewardRate = MathUtil.div(topGradeConfig.getDirectRewardRate(), ONE_HUNDRED,4);
		if(rewardRate.compareTo(BigDecimal.ZERO) == 0){
			return;
		}
		BigDecimal topRewardNum = MathUtil.mul(orderProductHrCombo.getOrderMoney(), rewardRate,8);
		boolean isLock = memberStoreLockUtils.lock(top1Member.getId(), comboDetails.getFromCoinsId());
		if (!isLock) {
			return;
		}
		memberStoreService.changeMemberStore(
				MemberStoreChange.builder()
						.memberId(top1Member.getId())
						.coinsId(comboDetails.getFromCoinsId())
						.coinsName(comboDetails.getFromCoinsName())
						.jaType(MemberJAType.PAY_FIL_ORDER_SHARE_1_SCALE)
						.orderId(orderProductHrCombo.getId())
						.custodyFee(BigDecimal.ZERO)
						.orderDetailId(comboDetails.getId())
						.changeNum(topRewardNum)
						.remark(me.getUserAccount() + ">" + top1Member.getUserAccount() + MemberJAType.PAY_FIL_ORDER_SHARE_1_SCALE.getMsg().toString())
						.build());
		memberStoreLockUtils.unlock(top1Member.getId(), comboDetails.getFromCoinsId());
	}

	/**
	 * 支付成功后续处理间推返U操作
	 *
	 * @param orderProductHrCombo
	 * @param comboDetails
	 */
	@SuppressWarnings("DuplicatedCode")
	public void payOrderShareIndirect2TopU(OrderProductHrCombo orderProductHrCombo, OrderProductHrComboDetails comboDetails) {
		//查询当前用户的上一级间推用户
		Member top2Member = memberService.getMemberTop2(orderProductHrCombo.getMemberId());
		if (ObjectUtils.isEmpty(top2Member)) {
			return;
		}
		//判断当前用户是否有算力订单
//        BigDecimal totalTo2EffectPowerNums = orderProductHrComboService.totalEffectiveOrderByMemberId(top2Member.getId(), CoinsEnum.FIL.getCode(), HashRateOrderEnums.Status.payed.getCode());
		BigDecimal totalTo2EffectPowerNums = orderProductHrComboService.totalEffectiveHrRateLargeThanZeroByMemberId(top2Member.getId());
		if (totalTo2EffectPowerNums.compareTo(BigDecimal.ZERO) > 0) {
			SysConfig top2PayShareConfig = sysConfigMapper.selectByName(ConfigConstants.PAY_FIL_ORDER_SHARE_2_SCALE);
			if (!ObjectUtils.isEmpty(top2PayShareConfig)) {
				Date currentDate = new Date();
				String pattern = "yyyy-MM-dd";
				String currentDateStr = DateFormatUtils.format(currentDate, pattern);
				BigDecimal shareTop2Usdt = new BigDecimal(top2PayShareConfig.getConfValue()).multiply(orderProductHrCombo.getOrderMoney());
				//给上一级用户分红订单购买数量USDT的百分比
				boolean isLock = memberStoreLockUtils.lock(top2Member.getId(), comboDetails.getCoinsId());
				if (!isLock) {
					return;
				}
				memberStoreService.changeMemberStore(
						MemberStoreChange.builder()
								.memberId(top2Member.getId())
								.coinsId(CoinsEnum.USDT.getCode())
								.coinsName(CoinsEnum.USDT.getName())
								.jaType(MemberJAType.PAY_FIL_ORDER_SHARE_2_SCALE)
								.orderId(orderProductHrCombo.getId())
								.custodyFee(BigDecimal.ZERO)
								.orderDetailId(comboDetails.getId())
								.changeNum(shareTop2Usdt)
								.remark(orderProductHrCombo.getMemberId() + ">" + top2Member.getId() + MemberJAType.PAY_FIL_ORDER_SHARE_2_SCALE.getMsg().toString())
								.build());
				memberStoreLockUtils.unlock(top2Member.getId(), comboDetails.getCoinsId());
			}
		}
	}

	/**
	 * @Description: 发放团队业绩奖励 购买货币
	 * @Author: ty
	 * @Date: 2021/6/23 17:03
	 * @param: []
	 * @return: void
	 **/
	public void sendTeamPerformanceReward(OrderProductHrCombo orderProductHrCombo, OrderProductHrComboDetails comboDetails){
		//根据购买用户推荐关系查询用户列表
		Member member = memberService.getMemberById(orderProductHrCombo.getMemberId());
		//用户推荐关系网络倒叙获取
		List<Integer> teamIds = listByUserPathDESC(member);
		if(!ObjectUtils.isEmpty(teamIds)){
			for(Integer memberId: teamIds){
				Member sonMember = memberService.getMemberById(memberId);
				if(ObjectUtils.isEmpty(sonMember)){
					break;
				}
				BigDecimal topEffect = orderProductHrComboService.totalEffectiveOrderAndStatusByMemberId(sonMember.getId());
				if(topEffect.compareTo(new BigDecimal(0)) <= 0){
					continue;
				}
				Integer rewardMemberId = 0;
				//获取当前用户的等级配置
				MemberGradeConfig sonGradeConfig = gradeConfigService.getById(sonMember.getVipGrade());
				//给用户的父级发放业绩奖
				Member parentMember = memberService.getMemberById(sonMember.getPid());
				BigDecimal rewardDivValue = BigDecimal.ZERO;
				if(!ObjectUtils.isEmpty(parentMember)){
					//给用户的父级等级配置
					MemberGradeConfig parentGradeConfig = gradeConfigService.getById(parentMember.getVipGrade());
					//判断用户是否是购买者，购买者上级用户不计算极差 直接拿对应的业绩奖励
					if(memberId == orderProductHrCombo.getMemberId()){
						rewardDivValue = parentGradeConfig.getPerformanceCommissionRate();
					}else{
						rewardDivValue = parentGradeConfig.getPerformanceCommissionRate().subtract(sonGradeConfig.getPerformanceCommissionRate());
					}
					rewardMemberId = parentMember.getId();
				}else{
					//顶级用户分红方式
					Integer directMemberId = getTopSecendMemberId(member);
					if(ObjectUtils.isEmpty(directMemberId)){
						return;
					}
					Member directMember = memberService.getMemberById(directMemberId);
					MemberGradeConfig directGradeConfig = gradeConfigService.getById(directMember.getVipGrade());
					rewardDivValue = sonGradeConfig.getPerformanceCommissionRate().subtract(directGradeConfig.getPerformanceCommissionRate());
					rewardMemberId = memberId;
				}
				rewardDivValue = MathUtil.div(rewardDivValue,ONE_HUNDRED,4);
				if(rewardDivValue.compareTo(BigDecimal.ZERO) <= 0){
					continue;
				}
				BigDecimal teamRewardNum = MathUtil.mul(orderProductHrCombo.getOrderMoney(),rewardDivValue,8);
				//发放父级业绩奖
				if(rewardMemberId == 0){
					continue;
				}
				boolean isLock = memberStoreLockUtils.lock(rewardMemberId, comboDetails.getFromCoinsId());
				if (!isLock) {
					continue;
				}
				memberStoreService.changeMemberStore(
						MemberStoreChange.builder()
								.memberId(rewardMemberId)
								.coinsId(comboDetails.getFromCoinsId())
								.coinsName(comboDetails.getFromCoinsName())
								.jaType(MemberJAType.PERFORMANCE_REWARD)
								.orderId(orderProductHrCombo.getId())
								.custodyFee(BigDecimal.ZERO)
								.orderDetailId(comboDetails.getId())
								.changeNum(teamRewardNum)
								.remark(MemberJAType.PERFORMANCE_REWARD.getMsg().toString())
								.build());
				memberStoreLockUtils.unlock(rewardMemberId, comboDetails.getFromCoinsId());
			}
		}
	}

	@Override
	public boolean isEnoughPayOrder(BigDecimal totalMoney, Integer memberId, List<PayTypeRep> payTypeList) {
		if (payTypeList.size() == 1) {
			PayTypeRep payTypeRep = payTypeList.get(0);
			payTypeRep.setPayMoney(totalMoney);
			MemberStore memberStore = memberStoreService.getMemberStore(memberId, payTypeRep.getCoinsName());
			return memberStore.getNum().compareTo(totalMoney) >= 0;
		} else {
			Map<String, BigDecimal> memberBalance = memberStoreService.getBalance2Map(memberId);
			Map<String, BigDecimal> coinPrice = coinsPriceService.getCoinsPrice2Map();
			for (PayTypeRep item : payTypeList) {
				BigDecimal payMoney = MathUtil.div(item.getPayRate().multiply(totalMoney), ONE_HUNDRED);

				if (!(coinPrice.containsKey(item.getCoinsName()) && memberBalance.containsKey(item.getCoinsName()))) {
					return false;
				}

				BigDecimal price = coinPrice.get(item.getCoinsName());
				item.setPayMoney(MathUtil.div(payMoney, price));
				if (memberBalance.get(item.getCoinsName()).compareTo(item.getPayMoney()) < 0) {
					return false;
				}

			}
			return true;
		}
	}

	@Override
	public List<PayRecord> getProductOrderPayRecord(Integer orderId, Integer payGroup, Integer orderType) {
		return getPayRecord(orderId, payGroup, orderType, MemberJAType.PAY_OTHER);
	}

	@Override
	public List<PayRecord> getProductHrComboPayRecord(Integer orderId, Integer payGroup, Integer orderType) {
		return getPayRecord(orderId, payGroup, orderType, MemberJAType.PAY_HR_COMBO);
	}

	private List<PayRecord> getPayRecord(Integer orderId, Integer payGroup, Integer orderType, MemberJAType jaType) {
		List<JournalAccount> memberJaList = memberJAService.list(new QueryWrapper<JournalAccount>().lambda()
				.eq(JournalAccount::getOrderId, orderId)
				.eq(JournalAccount::getJaType, jaType.getCode()));
		Map<String, PayTypeRep> payTypeMap = productPayTypeService.list2MapByOrderTypeAndPayGroup(orderType, payGroup);
		return memberJaList.stream().map(item -> PayRecord.builder().createTime(item.getCreateTime()).payGroup(payGroup)
				.payName(payTypeMap.get(item.getCoinsName()).getPayName()).coinsName(item.getCoinsName()).payNum(item.getJaNum()).build())
				.collect(Collectors.toList());
	}

	/**
	 * @Description: 根据用户路径获取用户除去自身的所有上级用户列表
	 * @Author: ty
	 * @Date: 2021/6/23 17:20
	 * @param: [buyMember]
	 * @return: java.util.List<com.service.dao.po.MemberCache>
	 **/
	public List<Integer> listByUserPathDESC(Member buyMember){
		if(ObjectUtils.isEmpty(buyMember)){
			return null;
		}
		String userPath = buyMember.getUserPath();
		if(ObjectUtils.isEmpty(userPath)){
			return null;
		}
		userPath = userPath+buyMember.getId();//将购买用户加入到数组中去

		String[] idStrs = userPath.split("-");
		List<Integer> memberIds = new ArrayList<>();
		for(String idStr : idStrs){
			if(ObjectUtils.isEmpty(idStr)){
				continue;
			}
//			else if(Integer.parseInt(idStr) == buyMember.getId()){
//				continue;
//			}
			memberIds.add(Integer.parseInt(idStr));
		}
		if(ObjectUtils.isEmpty(memberIds)){
			return null;
		}
		Collections.sort(memberIds,new Comparator<Integer>() {
			@Override
			public int compare(Integer o1, Integer o2) {
				// 返回值为int类型，大于0表示正序，小于0表示逆序
				return o2-o1;
			}
		});
		return memberIds;
	}

	/**
	 * @Description: 根据用户路径获取用户除去自身的所有上级用户列表
	 * @Author: ty
	 * @Date: 2021/6/23 17:20
	 * @param: [buyMember]
	 * @return: java.util.List<com.service.dao.po.MemberCache>
	 **/
	public List<Integer> splitByUserPathDESC(Member buyMember){
		if(ObjectUtils.isEmpty(buyMember)){
			return null;
		}
		String userPath = buyMember.getUserPath();
		if(ObjectUtils.isEmpty(userPath)){
			return null;
		}

		String[] idStrs = userPath.split("-");
		List<Integer> memberIds = new ArrayList<>();
		for(String idStr : idStrs){
			if(ObjectUtils.isEmpty(idStr)){
				continue;
			}
			memberIds.add(Integer.parseInt(idStr));
		}
		if(ObjectUtils.isEmpty(memberIds)){
			return null;
		}
		Collections.sort(memberIds,new Comparator<Integer>() {
			@Override
			public int compare(Integer o1, Integer o2) {
				// 返回值为int类型，大于0表示正序，小于0表示逆序
				return o2-o1;
			}
		});
		return memberIds;
	}

	/**
	 * @Description: 获取顶级用户的直推用户
	 * @Author: ty
	 * @Date: 2021/6/24 18:29
	 * @param: [buyMember]
	 * @return: java.lang.Integer
	 **/
	public Integer getTopSecendMemberId(Member buyMember){
		if(ObjectUtils.isEmpty(buyMember)){
			return null;
		}
		String userPath = buyMember.getUserPath();
		if(ObjectUtils.isEmpty(userPath)){
			return null;
		}
		String[] idStrs = userPath.split("-");
		List<Integer> memberIds = new ArrayList<>();
		for(String idStr : idStrs){
			if(ObjectUtils.isEmpty(idStr)){
				continue;
			}
			memberIds.add(Integer.parseInt(idStr));
		}
		if(ObjectUtils.isEmpty(memberIds)){
			return null;
		}
		Collections.sort(memberIds,new Comparator<Integer>() {
			@Override
			public int compare(Integer o1, Integer o2) {
				// 返回值为int类型，大于0表示正序，小于0表示逆序
				return o1-o2;
			}
		});
		if(memberIds.size() > 0){
			memberIds.remove(0);
		};
		if(memberIds.size() > 0){
			return memberIds.get(0);
		}else{
			return null;
		}
	}
}
